#pragma once
/*
模块说明:该模块给服务中心主机和提供Rpc调用的主机提供服务端
*/
#include "../Net.hpp"
#include "../Unit.hpp"
#include "../Dispatch.hpp"
#include "Rpc_Manager.hpp"
#include "Rpc_router.hpp"
#include "../Client/RpcClient.hpp"
#include "Rpc_TopicServer.hpp"
namespace Server
{
    // 该模块给负责管理主题信息的服务中心主机使用
    class TopicServer
    {
    public:
        using TopicServerPtr = std::shared_ptr<TopicServer>;
         TopicServer(uint16_t port) : _Dispatch(std::make_shared<Dispactch>()), _TopManager(std::make_shared<Topic::TopicManager>())
        {
            // 1 消息分发模块注册回调函数
            _Dispatch->RegisterHander(Rs_RqType::TOPIC_Req, [this](const Abstract::BaseConnection::ConPtr &Con, const Abstract::BaseMessage::MesaPtr &Mptr)
                                      { _TopManager->DealTopicRequest(Con, Mptr); });
            // 2 创建服务端对象即底层申请网络监听套接字绑定ip和port来接收客户端的连接并且返回对应的fd
            _Server = Net::BulidMuduoServer::bulid(port);
            // 3 主题（服务中心主机）服务端在接收到客户端主题请求时的回调处理函数
            _Server->SetReady_CallBack([this](const Abstract::BaseConnection::ConPtr &Con, const Abstract::BaseMessage::MesaPtr &Mptr)
                                       { _Dispatch->MessageCallback(Con, Mptr); }); // 设置服务端接收一条完整);

            // 订阅者主机和主题服务中心端主机连接断开时的回调函数
            _Server->SetClose_CallBack(
                [this](const Abstract::BaseConnection::ConPtr &Con)
                {
                    OnShutDown(Con);
                });
        }
        void Start()
        {
            _Server->start(); // 服务端启动开始监听所有的fd就绪事件
        }

    private:
        // Rpc提供主机和客户端主机连接断开时的回调函数
        void OnShutDown(const Abstract::BaseConnection::ConPtr &Con)
        {
            _TopManager->ShutDownCBack(Con);
        }

    private:
        Dispactch::DispaPtr _Dispatch;              // 消息分发模块
        Topic::TopicManager::TopicMPtr _TopManager; // 服务中心管理主题模块
        Abstract::BaseServer::SerPtr _Server;
    };

    // 该服务端模块给负责管理Rpc请求方和提供方消息服务中心使用
    class RegisterServer
    {
    public:
        using ServerPtr = std::shared_ptr<RegisterServer>;
        RegisterServer(uint16_t port) : _Dispatch(std::make_shared<Dispactch>()), _RpcPrDiMPtr(std::make_shared<Rpc_Manage::PrDiManager>())
        {
            // 1 消息分发模块注册回调函数
            _Dispatch->RegisterHander(Rs_RqType::Service_Req, [this](const Abstract::BaseConnection::ConPtr &Con, const Abstract::BaseMessage::MesaPtr &Mptr)
                                      { _RpcPrDiMPtr->DealServerRequest(Con, Mptr); });
            // 2 创建服务端对象即底层申请网络监听套接字绑定ip和port来接收客户端的连接并且返回对应的fd
            _Server = Net::BulidMuduoServer::bulid(port);
            // 3 注册服务端在接收到客户端服务发现请求时的回调处理函数
            _Server->SetReady_CallBack([this](const Abstract::BaseConnection::ConPtr &Con, const Abstract::BaseMessage::MesaPtr &Mptr)
                                       { _Dispatch->MessageCallback(Con, Mptr); }); // 设置服务端接收一条完整);

            // Rpc提供主机和客户端主机连接断开时的回调函数
            _Server->SetClose_CallBack(
                [this](const Abstract::BaseConnection::ConPtr &Con)
                {
                    OnShutDown(Con);
                });
        }
        void Start()
        {
            _Server->start(); // 服务端启动开始监听所有的fd就绪事件
        }

    private:
        // Rpc提供主机和客户端主机连接断开时的回调函数
        void OnShutDown(const Abstract::BaseConnection::ConPtr &Con)
        {
            _RpcPrDiMPtr->ShutDownBack(Con);
        }

    private:
        Dispactch::DispaPtr _Dispatch;                        // 消息分发模块
        Rpc_Manage::PrDiManager::PrDiManagerPtr _RpcPrDiMPtr; // 服务中心管理消息模块

        std::mutex _mutex;
        Abstract::BaseServer::SerPtr _Server;
    };

    // 提供Rpc服务的主机的客户端
    // 首先Rpc主机先服务中心注册能够提供的服务，发送服务名称字段和自己的外网的ip和端口,
    // 如果要注册服务那么要传入服务中心的主机信息
    class RpcServer
    {
    public:
        RpcServer(const Message::Address &OutHost, bool IsableReg = false, const Message::Address Server_Host = {"0.0.0.0", 100})
            : _Host(OutHost), _IsableReg(IsableReg), _Dispatch(std::make_shared<Dispactch>()), _RpcRouter(std::make_shared<RpcRouter::Rpc_Ruoter>())
        {
            // 如果启动服务注册功能
            if (IsableReg)
            {
                // 创建一个发起注册服务的客户端，创建的时候已经向服务中心发起连接了
                // 连接成功时创建了一个epoll线程去监听获取的fd即连接对象，然后主线程连接结束返回函数调用的地方
                RegPtr = std::make_shared<RpcClient::RegisterClient>(Server_Host.first, Server_Host.second);
            }
            // 1 注册消息分发模块的回调函数
            _Dispatch->RegisterHander(Rs_RqType::RPC_Req,
                                      [this](const Abstract::BaseConnection::ConPtr &Con, const Abstract::BaseMessage::MesaPtr &Mptr)
                                      {
                                          _RpcRouter->DealRpcQuest(Con, Mptr);
                                      });
            // 2 创建网络监听套接字绑定端口和ip
            _Server = Net::BulidMuduoServer::bulid(OutHost.second);
            _Server->SetReady_CallBack(
                [this](const Abstract::BaseConnection::ConPtr &Con, const Abstract::BaseMessage::MesaPtr &Mptr)
                {
                    _Dispatch->MessageCallback(Con, Mptr);
                }); // 设置服务端接收一条完整
        }
        // 注册实际的业务回调函数
        void RegisterMethod(const RpcRouter::SeverDesc::ServerDes_ptr &ServerDes)
        {
            if (_IsableReg) // 如果启动了 服务注册功能那么先向服务中心发送服务注册请求并且阻塞等待回应
            {
                RegPtr->RegisterMethod(ServerDes->GetMethod(), _Host);
            }
            // 注册实际的服务描述对象，将来接收到Rpc请求时进入回调函数查找对应的服务描述对象
            // 将参数进行对比符合条件就进行实际的业务处理
            _RpcRouter->RegisterSerDec(ServerDes);
        }
        void Start()
        {
            // 当前线程开始死循环监听所有的套接字就绪事件
            // 如果有客户端的消息到来就会触发设置好的回调函数进行处理
            _Server->start();
        }
        // 关闭和服务中心的链接
        void ShutDownRegisterConnection()
        {
            if (_IsableReg)
            {
                RegPtr->ShutDown();
            }
        }

    private:
        Message::Address _Host; // 提供Rpc服务的主机的公网ip和端口
        bool _IsableReg;
        Dispactch::DispaPtr _Dispatch;                  // 消息分发模块
        RpcRouter::Rpc_Ruoter::RpcRouterPtr _RpcRouter; // 接收到客户端的Rpc请求后处理请求的路由模块
        std::mutex _mutex;
        std::shared_ptr<RpcClient::RegisterClient> RegPtr; // 注册Rpc服务客户端模块--负责向服务中心发起Rpc注册请求
        Abstract::BaseServer::SerPtr _Server;              // 服务端网络通信模块
    };

};